package uml.eventsystem;

import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;

import uml.eventsystem.events.UMLEvent;
import uml.eventsystem.events.UMLEventId;

/**
 * Implementation of the ISubject interface.
 */
public class SubjectImpl
		implements ISubject
{
	private EnumMap<UMLEventId, ArrayList<IObserver>> m_observerMap;
	Object m_source;

	/**
	 * Constructor.
	 */
	private SubjectImpl ()
	{

	}

	/**
	 * constructor that takes an object source
	 * 
	 * @param source
	 */
	public SubjectImpl (Object source)
	{
		m_source = source;
		m_observerMap = new EnumMap<UMLEventId, ArrayList<IObserver>> (UMLEventId.class);

		// Initialize all event IDs with empty lists
		for (UMLEventId ueId : UMLEventId.values ())
		{
			m_observerMap.put (ueId, new ArrayList<IObserver> ());
		}
	}

	/**
	 * adds an observer and associated eventId
	 */
	@Override
	public void addObserver (IObserver observer, UMLEventId eventId)
	{
		Collection<IObserver> listeners = m_observerMap.get (eventId);
		listeners.add (observer);
	}

	/**
	 * removes an observer and associated eventId
	 */
	@Override
	public void removeObserver (IObserver observer, UMLEventId eventId)
	{
		Collection<IObserver> observerList = m_observerMap.get (eventId);
		observerList.remove (observer);
	}

	/**
	 * notifies observers of eventId
	 */
	@Override
	public void notifyObservers (UMLEventId eventId)
	{
		notifyObservers (new UMLEvent (eventId, m_source));
	}

	/**
	 * notifies observers of an event
	 */
	public void notifyObservers (UMLEvent event)
	{
		if (m_observerMap.containsKey (event.getEventId ()))
		{
			Collection<IObserver> observerList = m_observerMap.get (event.getEventId ());
			for (IObserver observer : observerList)
			{
				observer.handleNotification (event);
			}
		}
	}
}
